<!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="utf8">
  <title>Test that the network actor uses the LongStringActor</title>
  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript;version=1.8" src="common.js"></script>
  <!-- Any copyright is dedicated to the Public Domain.
     - http://creativecommons.org/publicdomain/zero/1.0/ -->
</head>
<body>
<p>Test that the network actor uses the LongStringActor</p>

<iframe src="http://example.com/chrome/devtools/shared/webconsole/test/network_requests_iframe.html"></iframe>

<script class="testbody" type="text/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();

function startTest()
{
  removeEventListener("load", startTest);

  attachConsoleToTab(["NetworkActivity"], onAttach);
}

function onAttach(aState, aResponse)
{
  info("set long string length");

  window.ORIGINAL_LONG_STRING_LENGTH = DebuggerServer.LONG_STRING_LENGTH;
  window.ORIGINAL_LONG_STRING_INITIAL_LENGTH =
    DebuggerServer.LONG_STRING_INITIAL_LENGTH;

  DebuggerServer.LONG_STRING_LENGTH = 400;
  DebuggerServer.LONG_STRING_INITIAL_LENGTH = 400;

  info("test network POST request");

  onNetworkEvent = onNetworkEvent.bind(null, aState);
  aState.dbgClient.addListener("networkEvent", onNetworkEvent);
  onNetworkEventUpdate = onNetworkEventUpdate.bind(null, aState);
  aState.dbgClient.addListener("networkEventUpdate", onNetworkEventUpdate);

  let iframe = document.querySelector("iframe").contentWindow;
  iframe.wrappedJSObject.testXhrPost();
}

function onNetworkEvent(aState, aType, aPacket)
{
  is(aPacket.from, aState.actor, "network event actor");

  info("checking the network event packet");

  let netActor = aPacket.eventActor;

  checkObject(netActor, {
    actor: /[a-z]/,
    startedDateTime: /^\d+\-\d+\-\d+T.+$/,
    url: /data\.json/,
    method: "POST",
  });

  aState.netActor = netActor.actor;

  aState.dbgClient.removeListener("networkEvent", onNetworkEvent);
}

let updates = [];

function onNetworkEventUpdate(aState, aType, aPacket)
{
  info("received networkEventUpdate " + aPacket.updateType);
  is(aPacket.from, aState.netActor, "networkEventUpdate actor");

  updates.push(aPacket.updateType);

  let expectedPacket = null;

  switch (aPacket.updateType) {
    case "requestHeaders":
    case "responseHeaders":
      ok(aPacket.headers > 0, "headers > 0");
      ok(aPacket.headersSize > 0, "headersSize > 0");
      break;
    case "requestCookies":
      expectedPacket = {
        cookies: 3,
      };
      break;
    case "requestPostData":
      ok(aPacket.dataSize > 0, "dataSize > 0");
      ok(!aPacket.discardRequestBody, "discardRequestBody");
      break;
    case "responseStart":
      expectedPacket = {
        response: {
          httpVersion: /^HTTP\/\d\.\d$/,
          status: "200",
          statusText: "OK",
          headersSize: /^\d+$/,
          discardResponseBody: false,
        },
      };
      break;
    case "securityInfo":
      expectedPacket = {
        state: "insecure",
      };
      break;
    case "responseCookies":
      expectedPacket = {
        cookies: 0,
      };
      break;
    case "responseContent":
      expectedPacket = {
        mimeType: "application/json",
        contentSize: /^\d+$/,
        discardResponseBody: false,
      };
      break;
    case "eventTimings":
      expectedPacket = {
        totalTime: /^\d+$/,
      };
      break;
    default:
      ok(false, "unknown network event update type: " +
         aPacket.updateType);
      return;
  }

  if (expectedPacket) {
    info("checking the packet content");
    checkObject(aPacket, expectedPacket);
  }

  if (updates.indexOf("responseContent") > -1 &&
      updates.indexOf("eventTimings") > -1) {
    aState.dbgClient.removeListener("networkEventUpdate",
                                    onNetworkEvent);

    onRequestHeaders = onRequestHeaders.bind(null, aState);
    aState.client.getRequestHeaders(aState.netActor,
                                    onRequestHeaders);
  }
}

function onRequestHeaders(aState, aResponse)
{
  info("checking request headers");

  ok(aResponse.headers.length > 0, "request headers > 0");
  ok(aResponse.headersSize > 0, "request headersSize > 0");

  checkHeadersOrCookies(aResponse.headers, {
    Referer: /network_requests_iframe\.html/,
    Cookie: /bug768096/,
  });

  onRequestCookies = onRequestCookies.bind(null, aState);
  aState.client.getRequestCookies(aState.netActor,
                                  onRequestCookies);
}

function onRequestCookies(aState, aResponse)
{
  info("checking request cookies");

  is(aResponse.cookies.length, 3, "request cookies length");

  checkHeadersOrCookies(aResponse.cookies, {
    foobar: "fooval",
    omgfoo: "bug768096",
    badcookie: "bug826798=st3fan",
  });

  onRequestPostData = onRequestPostData.bind(null, aState);
  aState.client.getRequestPostData(aState.netActor,
                                   onRequestPostData);
}

function onRequestPostData(aState, aResponse)
{
  info("checking request POST data");

  checkObject(aResponse, {
    postData: {
      text: {
        type: "longString",
        initial: /^Hello world! foobaz barr.+foobaz barrfo$/,
        length: 552,
        actor: /[a-z]/,
      },
    },
    postDataDiscarded: false,
  });

  is(aResponse.postData.text.initial.length,
     DebuggerServer.LONG_STRING_INITIAL_LENGTH, "postData text initial length");

  onResponseHeaders = onResponseHeaders.bind(null, aState);
  aState.client.getResponseHeaders(aState.netActor,
                                   onResponseHeaders);
}

function onResponseHeaders(aState, aResponse)
{
  info("checking response headers");

  ok(aResponse.headers.length > 0, "response headers > 0");
  ok(aResponse.headersSize > 0, "response headersSize > 0");

  checkHeadersOrCookies(aResponse.headers, {
    "content-type": /^application\/(json|octet-stream)$/,
    "content-length": /^\d+$/,
    "x-very-short": "hello world",
    "x-very-long": {
      "type": "longString",
      "length": 521,
      "initial": /^Lorem ipsum.+\. Donec vitae d$/,
      "actor": /[a-z]/,
    },
  });

  onResponseCookies = onResponseCookies.bind(null, aState);
  aState.client.getResponseCookies(aState.netActor,
                                  onResponseCookies);
}

function onResponseCookies(aState, aResponse)
{
  info("checking response cookies");

  is(aResponse.cookies.length, 0, "response cookies length");

  onResponseContent = onResponseContent.bind(null, aState);
  aState.client.getResponseContent(aState.netActor,
                                   onResponseContent);
}

function onResponseContent(aState, aResponse)
{
  info("checking response content");

  checkObject(aResponse, {
    content: {
      text: {
        type: "longString",
        initial: /^\{ id: "test JSON data"(.|\r|\n)+ barfoo ba$/g,
        length: 1070,
        actor: /[a-z]/,
      },
    },
    contentDiscarded: false,
  });

  is(aResponse.content.text.initial.length,
     DebuggerServer.LONG_STRING_INITIAL_LENGTH, "content initial length");

  onEventTimings = onEventTimings.bind(null, aState);
  aState.client.getEventTimings(aState.netActor,
                                onEventTimings);
}

function onEventTimings(aState, aResponse)
{
  info("checking event timings");

  checkObject(aResponse, {
    timings: {
      blocked: /^-1|\d+$/,
      dns: /^-1|\d+$/,
      connect: /^-1|\d+$/,
      send: /^-1|\d+$/,
      wait: /^-1|\d+$/,
      receive: /^-1|\d+$/,
    },
    totalTime: /^\d+$/,
  });

  closeDebugger(aState, function() {
    DebuggerServer.LONG_STRING_LENGTH = ORIGINAL_LONG_STRING_LENGTH;
    DebuggerServer.LONG_STRING_INITIAL_LENGTH = ORIGINAL_LONG_STRING_INITIAL_LENGTH;

    SimpleTest.finish();
  });
}

addEventListener("load", startTest);
</script>
</body>
</html>
